This post will mainly be about my experience getting OvenMediaEngine up and running, as well as OvenPlayer. I would like to preface this by saying that this isn’t exactly a guide, much less a comprehensive one. It will be written based on what I did and found to be the easiest for my use case and setup. You are still strongly recommended to study the official documents#getting-started and alter the steps according to your needs.

Just a quick recap, I’m self-hosting this on my Raspberry Pi 4 8GB running the 64-bit Raspbian beta. Should you be more interested in seeing what other solutions are out there and my experiences using them you can refer to my previous post : Self-Hosted Live Streaming Platform

Let’s Start!

Building The Image

UPDATE 2: 
It seems that they have started publishing their official images with both x86 and ARM64 support, so I'd say its best to just use theirs unless you have other plans in mind.

UPDATE:
For those struggling to build the images themselves and wants to skip all the hassle, I've pushed a build for you to try. Instead of pulling airensoft/ovenmediaengine, use leejacksonz/ovenmediaengine:v0.15.8
I'm not sure how often I'll update the images, but I'll most likely update them when I update my own deployments... but no guarantees :P

So, there are a few ways of installing OME, either by installing it directly(using the official script) or using a docker image.

Personally, I chose to use a docker image as it consolidates everything and makes things simpler in my opinion, but it does mean that it’ll require some basic docker know-how.

At first, I tried using the official script to install OME, but then I faced quite a few errors and it was a total mess. Probably a me problem but I just couldn’t be bothered to deal with it. So then, I turned to Docker. To be fair, I didn’t have much experience with Docker prior to this, having only learn the basics of it when I was tinkering with Project-Lightspeed.

Initially, I thought all I had to do was to just pull the official image from Docker, but as it turns out, the image on Docker Hub didn’t have builds for ARM64, which is what I need for my Raspberry Pi. So, first thing that I had to do was to build my own image. However, if you’re doing this on an x86/64 system then feel free to use the official image by following the guide on the Docker Hub.

Start by cloning the GitHub repository. I’ve decided its better to clone the release branch as occasionally I had some difficulties compiling with the master branch. YMMV This took quite some time to build on my RPi4, and the CPU was pinned at 100% most of the time, so do ensure you have adequate cooling for it.

cd ~
git clone -b release https://github.com/AirenSoft/OvenMediaEngine.git
cd OvenMediaEngine
docker --no-cache build -t ome:1.0 .

Side note, I tagged this image as 1.0. Should you decide to rebuild an updated version(by cloning the git again) you may change it to 2.0 and so on. But, I suppose you could also tag it by its real version number if you prefer that.

Also, I built this image with the 8GB RPi4 and noticed that at certain stages of the build process, the RAM was almost fully used up, and the RPi would crash if it ran out of ram. I had to increase the default 100MB swap to 2GBs, and from my observation, it maxed out at 260MB swap. I’m unsure what would happen if you have 4GB or less. You’d probably need to consider increasing the swap even more or just building the image on your PC with Docker’s buildx.

Creating the Docker Container

Once the image is done building, let’s create a .sh script to create the container. This is useful in the future when you want to update the image and rebuild the container.

sudo nano createOME.sh

Paste the following in nano.

sudo docker run -d \
--expose=3334 \
-p 1935:1935 \
-p 3333:3333 \
-p 3334:3334 \
-p 8080:8080 \
-p 8443:8443 \
-p 9999:9999/udp \
-p 10006-10010:10006-10010/udp \
-v ome-origin-conf:/opt/ovenmediaengine/bin/origin_conf \
-v ome-edge-conf:/opt/ovenmediaengine/bin/edge_conf \
-v /PATH/TO/YOUR/CERT/:/cert \
--name ovenmediaengine \
ome:1.0

In this script, I’ve opened the necessary ports for OME and created docker volumes to store the configuration files so that it persists even if the container is removed. It is also going to be easier to modify the configuration file in the host environment, and also makes troubleshooting and rebuilding the container a breeze. Feel free to modify this script for your needs.

Refer to this #Getting Started with Docker for more details on Docker configurations. Info on the ports are there,

If you intend to use HTTPS(which you should), you need to add an extra mount point that points to your certificates. Just replace “/PATH/TO/YOUR/CERT/” with the path of the folder containing your certificates, otherwise, it will not work. In my case, since I’m using certbot, I pointed the path to certbot’s directory as such: “/etc/letsencrypt/:/letsencrypt”
This is a requirement as by default, most modern browser doesn’t allow mixed-mode operations. As such, you must use secure variants of the providers, eg secure WebSockets for WebRTC, or the TLS version of HLS.

‘Ctrl+X’ to exit, ‘Y’ to save, ‘Enter’ to confirm the name.

sudo chmod +x createOME.sh
./createOME.sh

Make the script executable and run it. If all is well, the OME docker container should be up and running. The installation part of OME is complete, now onto the configuration.

Configuring Stuff

There are quite some stuff that to tweak in the config file. Namely, enabling TLS, configuring the hostname, and adding your certs. I also disabled TCP for WebRTC(enabled by default) and enabled Ulpfec and Rtx. If this sounds little daunting, don’t be! It just some smart retransmission stuff for UDP.

UPDATE:
After a bunch of testing, I’ve decided against doing any of this, refer to the performance optimisation section of this post. Someone has actually done more in-depth testing of different WebRTC config in OME, and their findings check out with mine. Do check it out!

Start by editing the config file.

sudo nano /var/lib/docker/volumes/ome-origin-conf/_data/Server.xml

Save any changes you’ve made. You need to restart your container for the changes to take effect. Fingers crossed that there are no major error and the container starts. You can use this tool to check that there arent any syntax errors. https://www.xmlvalidation.com/

Here’s my config file for reference. I have enabled TLS for WebRTC and DASH/HLS at port 3334 and 8443 respectively. You can set it to any ports as you please, but do make sure those ports are opened in the docker container(refer back to the initial createOME.sh)

As always, refer to the documentation#configuration for the specific config options.

When trying to set up OME, it might be easier for you to run the script without the detached flag, just remove ‘-d’ from the first line of the script.

Line 102/103 : Make sure to put your domain or IP of your server. Add/remove as needed.
Line 106-110: Change file name of certificate as needed, can if commented out/omited if not used.
Note: Remember to remove "<!--" & "-->" completely, this is a helpful tip for someone like me who doesn't deal with XML that much lol.

<?xml version="1.0" encoding="UTF-8" ?>
<Server version="8">
	<Name>OvenMediaEngine</Name>
	<!-- Host type (origin/edge) -->
	<Type>origin</Type>
	<!-- Specify IP address to bind (* means all IPs) -->
	<IP>*</IP>
	<PrivacyProtection>false</PrivacyProtection>
	<!-- 
	To get the public IP address(mapped address of stun) of the local server. 
	This is useful when OME cannot obtain a public IP from an interface, such as AWS or docker environment. 
	If this is successful, you can use ${PublicIP} in your settings.
	-->
	<StunServer>stun.l.google.com:19302</StunServer>
	<!-- Settings for the ports to bind -->
	<Bind>
		<!-- Enable this configuration if you want to use API Server -->
		<!--
		<Managers>
			<API>
				<Port>${env:OME_API_PORT:8081}</Port>
				<WorkerCount>1</WorkerCount>
			</API>
		</Managers>
		-->
		<Providers>
			<!-- Pull providers -->
			<RTSPC>
				<WorkerCount>1</WorkerCount>
			</RTSPC>
			<OVT>
				<WorkerCount>1</WorkerCount>
			</OVT>
			<!-- Push providers -->
			<RTMP>
				<Port>${env:OME_RTMP_PROV_PORT:1935}</Port>
				<WorkerCount>1</WorkerCount>
			</RTMP>
			<SRT>
				<Port>${env:OME_SRT_PROV_PORT:9999}</Port>
				<WorkerCount>1</WorkerCount>
			</SRT>
			<MPEGTS>
				<!--
					Listen on port 4000-4005
					This is just a demonstration to show that you can configure the port in several ways
				-->
				<Port>${env:OME_MPEGTS_PROV_PORT:4000/udp}</Port>
			</MPEGTS>
			<WebRTC>
				<Signalling>
					<Port>${env:OME_SIGNALLING_PORT:3333}</Port>
					<WorkerCount>1</WorkerCount>
					<!-- If you want to use TLS, specify the TLS port -->
					<TLSPort>3334</TLSPort>
				</Signalling>
				<IceCandidates>
					<TcpRelay>${env:OME_TCP_RELAY_ADDRESS:*:3478}</TcpRelay>
					<TcpForce>false</TcpForce>
					<TcpRelayWorkerCount>1</TcpRelayWorkerCount>
					<IceCandidate>${env:OME_ICE_CANDIDATES:*:10006/udp}</IceCandidate>
				</IceCandidates>
			</WebRTC>
		</Providers>
		<Publishers>
			<!-- The OVT is protocol for ORIGIN-EDGE -->
			<OVT>
				<Port>${env:OME_ORIGIN_PORT:9000}</Port>
				<WorkerCount>1</WorkerCount>
			</OVT>
			<HLS>
				<Port>${env:OME_HLS_STREAM_PORT:8080}</Port>
				<WorkerCount>1</WorkerCount>
				<!-- If you want to use TLS, specify the TLS port -->
				<TLSPort>8443</TLSPort>
			</HLS>
			<DASH>
				<Port>${env:OME_DASH_STREAM_PORT:8080}</Port>
				<WorkerCount>1</WorkerCount>
				<!-- If you want to use TLS, specify the TLS port -->
				<TLSPort>8443</TLSPort>
			</DASH>
			<WebRTC>
				<Signalling>
					<Port>${env:OME_SIGNALLING_PORT:3333}</Port>
					<WorkerCount>1</WorkerCount>
					<!-- If you want to use TLS, specify the TLS port -->
					<TLSPort>3334</TLSPort>
				</Signalling>
				<IceCandidates>
					<TcpRelay>${env:OME_TCP_RELAY_ADDRESS:*:3478}</TcpRelay>
					<TcpForce>false</TcpForce>
					<TcpRelayWorkerCount>1</TcpRelayWorkerCount>
					<IceCandidate>${env:OME_ICE_CANDIDATES:*:10006/udp}</IceCandidate>
				</IceCandidates>
			</WebRTC>
		</Publishers>
	</Bind>
	<VirtualHosts>
		<!--
			You can include multiple XML files by doing the following:
			<VirtualHost include="sites-enabled/*.xml" />
		-->
		<VirtualHost include="VHost*.xml" />
		<VirtualHost>
			<Name>default</Name>
			<!--Distribution is a value that can be used when grouping the same vhost distributed across multiple servers. This value is output to the events log, so you can use it to aggregate statistics. -->
			<Distribution>ovenmediaengine.com</Distribution>
			
			<!-- Settings for multi ip/domain and TLS -->
			<Host>
				<Names>
					<Name>your.address.com</Name>
					<Name>192.168.1.69</Name>
				</Names>
				
				<TLS>
					<CertPath>/cert/cert.pem</CertPath>
					<KeyPath>/cert/privkey.pem</KeyPath>
					<ChainCertPath>/cert/chain.pem</ChainCertPath>
				</TLS>
				
			</Host>
			<!-- Refer https://airensoft.gitbook.io/ovenmediaengine/signedpolicy
			<SignedPolicy>
				<PolicyQueryKeyName>policy</PolicyQueryKeyName>
				<SignatureQueryKeyName>signature</SignatureQueryKeyName>
				<SecretKey>aKq#1kj</SecretKey>
				<Enables>
					<Providers>rtmp,webrtc,srt</Providers>
					<Publishers>webrtc,hls,dash,lldash</Publishers>
				</Enables>
			</SignedPolicy>
			-->
			<!-- Settings for applications -->
			<Applications>
				<Application>
					<Name>app</Name>
					<!-- Application type (live/vod) -->
					<Type>live</Type>
					<OutputProfiles>
						<OutputProfile>
							<Name>bypass_stream</Name>
							<OutputStreamName>${OriginStreamName}</OutputStreamName>
							<Encodes>
								<Audio>
									<Bypass>true</Bypass>
								</Audio>
								<Video>
									<Bypass>true</Bypass>
								</Video>
								<Audio>
									<Codec>opus</Codec>
									<Bitrate>128000</Bitrate>
									<Samplerate>48000</Samplerate>
									<Channel>2</Channel>
								</Audio>
							</Encodes>
						</OutputProfile>
					</OutputProfiles>
					<Providers>
						<OVT />
						<WebRTC />
						<RTMP />
						<SRT />
						<RTSPPull />
						<MPEGTS>
							<StreamMap>
								<!--
									Set the stream name of the client connected to the port to "stream_${Port}"
									For example, if a client connets to port 4000, OME creates a "stream_4000" stream
									<Stream>
										<Name>stream_${Port}</Name>
										<Port>4000,4001-4004</Port>
									</Stream>
									<Stream>
										<Name>stream_4005</Name>
										<Port>4005</Port>
									</Stream>
								-->
								<Stream>
									<Name>stream_${Port}</Name>
									<Port>4000</Port>
								</Stream>
							</StreamMap>
						</MPEGTS>
					</Providers>
					<Publishers>
						<AppWorkerCount>1</AppWorkerCount>
						<StreamWorkerCount>3</StreamWorkerCount>
						<OVT />
						<WebRTC>
							<Timeout>30000</Timeout>
							<Rtx>false</Rtx>
							<Ulpfec>false</Ulpfec>
							<JitterBuffer>true</JitterBuffer>
						</WebRTC>
						<HLS>
							<SegmentDuration>1</SegmentDuration>
							<SegmentCount>1</SegmentCount>
							<CrossDomains>
								<Url>*</Url>
							</CrossDomains>
						</HLS>
						<DASH>
							<SegmentDuration>1</SegmentDuration>
							<SegmentCount>1</SegmentCount>
							<CrossDomains>
								<Url>*</Url>
							</CrossDomains>
							<UTCTiming />
						</DASH>
						<LLDASH>
							<SegmentDuration>1</SegmentDuration>
							<CrossDomains>
								<Url>*</Url>
							</CrossDomains>
							<UTCTiming />
						</LLDASH>
					</Publishers>
				</Application>
			</Applications>
		</VirtualHost>
	</VirtualHosts>
</Server>

Time To Test!

Now it’s time to test and see if OME is working. To do that, we can just do a quick test stream through OBS and see if OBS can successfully establish a stream with OME. During testing, it is extremely helpful to check the output logs from the OME. Most of the time the errors are fairly self-explanatory.

At first, I got a little confused trying to understand the documentation, but here’s how to set it up in OBS.

rtmp://your.ome.server.ip:1935/app/ (stream key : stream)
srt://your.ome.server.ip:9999?streamid=srt%3A//your.ome.server.ip%3A9999/app/stream%3Fquery%3Dvalue

In OBS, go to Settings > Stream. From the drop-down menu pick custom server. As OME supports multiple ingest methods, do refer to the guide for more detailed explanation.

I tried out both RTMP and SRT and to be honest, I couldn’t really tell the difference. SRT is supposed to perform better over long distances and has more features. For what I’m using it for it doesn’t really matter, but I personally would prefer SRT over RTMP.

If everything is working, a green box with the bitrate next to it should appear at the bottom right of OBS.

A very useful debugging step should you face issues is that you could attach to your docker container and check the console output of OME. I’d recommend Portainer when managing docker as it does seriously make life easier.

Now, if we have successfully connected to the server, it time we tweak some settings to optimise for WebRTC streaming. Head on over to Settings > Output. Change output mode from Simple to Advanced. Make sure you pick hardware encoding whenever possible and most importantly change Keyframe Interval to 1 and change the profile to baseline. Otherwise, from my testing, WebRTC will be a stutter-y mess.

Windows NVENC
macOS M1

Quick intermission

In the config, you can actually have multiple profiles set up. You may have noticed that I used the term ‘app’ and ‘stream’ in the streaming address. OME actually supports multiple streams and multiple streaming configurations. The official documentation#application puts it best,

<Application> consists of various elements that can define the operation of the stream, including Stream input, Encoding, and Stream output. In other words, you can create as many <Application> as you like and build various streaming environments.”

‘app’ actually corresponds to the default profile of the stream. You can configure the video and audio settings, whether or not you want to transcode it etc. But if you’re unsure best to just leave it be!

On the other hand, ‘stream’ actually refers to the name of the stream. Let’s say you have two OBS streams; the first OBS’ stream key could be called ‘obs1’, and the second one could be called ‘obs2’. With this, you could have multiple streams, and you’d be able to select them in OvenPlayer.

You can learn more about this in the official documentation#publish.

Using OvenPlayer

Once the stream from OBS to OME is successful, we need to test the other half of this streaming setup, the actual viewing of the stream.

To view your stream, all you need to do is just enter the address for the streams that you want. Conveniently, there is a test site where you can test your stream. It’s http://demo.ovenplayer.com. There is also the HTTPS version of the site, but it’ll only work for secure TLS streams. Make sure to use the correct secure or non secure variant and its corresponding ports. ie ws(port 3333) vs wss(port 3334).

WebRTC : ws(s)://your.address:port/app/stream
HLS  : http(s)://your.address:port/app/stream/playlist.m3u8
DASH : http(s)://your.address:port/app/stream/manifest.mpd
LLDASH : http(s)://your.address:port/app/stream/manifest_ll.mpd

If it works then great! Now, you have a working live streaming setup, and it is up to you to create a site to host the OvenPlayer.

Unfortunately, I won’t be going in-depth into how to do this part, but for your reference, here’s my simple web page.

<head>
	<title>OvenPlayer</title>
	<link rel="shortcut icon" href="https://static.wixstatic.com/media/a9e07d_e87d2349ea3b43dba66ec6ea4ec37e9a%7Emv2.png/v1/fill/w_32%2Ch_32%2Clg_1%2Cusm_0.66_1.00_0.01/a9e07d_e87d2349ea3b43dba66ec6ea4ec37e9a%7Emv2.png" type="image/png">
    <style>
        .wrapper{
            max-width: 900px;
            margin: 0 auto;
        }
    </style>
</head>
<body style="background-color:black;">
    <div class="wrapper">
        <div id="player"></div>
        <pre>
        </pre>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/ovenplayer/dist/ovenplayer.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest/dist/hls.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/dashjs@latest/dist/dash.all.debug.min.js"></script>
    <script>
        var player = OvenPlayer.create("player", { autoStart : true, autoFallback : true ,mute : true,
			sources: [
                {
                    "file": "wss://your.address:port/app/stream",
                    "label": "whateveryouwant",
                    "type": "webrtc" 
                },
                {
                    "file": "wss://your.address:3334/app/obs1",
                    "label": "OBS 2",
                    "type": "webrtc" 
                },
                {
                    "file":"https://your.address:8443/app/obs2/playlist.m3u8",
                    "label": "OBS 2",
                    "type": "hls" 
                },
                {
                    "file":"https://your.address:8443/app/stream4/manifest.mpd",
                    "label": "Stream 4",
                    "type": "dash" 
                }
            ]
        });
        hljs.initHighlightingOnLoad();
    </script>
</body>

For line 24-44, the bottom of the demo site conveniently generates the necessary code snippets for you to add your sources.

It should also be noted that OvenPlayer itself is also capable of a lot of stuff, playing regular media files, ads monetisation, customisation etc. However, this is more than good enough for my use-case. If you’re curious, you can always have a look at its documentation.

For me, I chose to use Cloudflare’s Worker’s to host my streaming site using its free workers. But basically, I created a worker, pasted my script and pointed a subdomain to the worker’s address. I’ll likely cover more on Cloudflare worker but as it stands, there’s a lot more to learn before I dare make a post about it lol.

This use case is documented here.

const html = `<!DOCTYPE html>
<head>
	<title>OvenPlayer</title>
	<link rel="shortcut icon" href="https://static.wixstatic.com/media/a9e07d_e87d2349ea3b43dba66ec6ea4ec37e9a%7Emv2.png/v1/fill/w_32%2Ch_32%2Clg_1%2Cusm_0.66_1.00_0.01/a9e07d_e87d2349ea3b43dba66ec6ea4ec37e9a%7Emv2.png" type="image/png">
    <style>
        .wrapper{
            max-width: 900px;
            margin: 0 auto;
        }
    </style>
</head>
<body style="background-color:black;">
    <div class="wrapper">
        <div id="player"></div>
        <pre>
        </pre>
    </div>
        <script src="https://cdn.jsdelivr.net/npm/ovenplayer/dist/ovenplayer.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest/dist/hls.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/dashjs@latest/dist/dash.all.debug.min.js"></script>
    <script>
        var player = OvenPlayer.create("player", { autoStart : true, mute : true,
			sources: [
                {
                    "file": "wss://your.address:port/app/stream",
					"label": "whateveryouwant",
					"type": "webrtc" 
                }
            ]
        });
        hljs.initHighlightingOnLoad();
    </script>
</body>`
async function handleRequest(request) {
  return new Response(html, {
    headers: {
      "content-type": "text/html;charset=UTF-8",
    },
  })
}
addEventListener("fetch", event => {
  return event.respondWith(handleRequest(event.request))
})

Origin-Edge Configurations

Overview of OME clustering architecture

Another cool thing you can do with OME is you can scale your setup horizontally by having multiple edge servers. For me, I’m using it to overcome poor routing from my home ISP, not so much about scaling it.

The way that OME handles this is through the use of its own protocol called OVT. It is based on SRT for delivering the video stream from the origin servers to the edge servers. The origin server will essentially have another publisher configured(OVT in addition to WebRTC, HLS etc), and the edge server will have another provider configured(OVT in addition to RTMP, SRT etc). Configuration-wise, it is fairly similar!

Similar to our initial startOME.sh script, we now need to open port 9000 for both the origin and the edge.

sudo docker run -d \
--expose=3334 \
-p 1935:1935 \
-p 3333:3333 \
-p 3334:3334 \
-p 3478:3478 \
-p 8443:8443 \
-p 9000:9000 \
-p 9999:9999/udp \
-p 10006-10010:10006-10010/udp \
-v ome-origin-conf:/opt/ovenmediaengine/bin/origin_conf \
-v ome-edge-conf:/opt/ovenmediaengine/bin/edge_conf \
-v /etc/letsencrypt/:/letsencrypt \
--name ovenmediaengine \
leejacksonz/ovenmediaengine:v0.15.8

Enabling OVT on the Origin Server

For the origin side, just make sure that the publisher for OVT is enabled. Check configuration#clustering(origin)

<Publishers>	
			<!-- The OVT is protocol for ORIGIN-EDGE -->	
			<OVT>	
				<Port>${env:OME_ORIGIN_PORT:9000}</Port>	
				<WorkerCount>1</WorkerCount>	
			</OVT>	
			<HLS>	
				<Port>${env:OME_HLS_STREAM_PORT:8080}</Port>	
				<WorkerCount>1</WorkerCount>	
				<!-- If you want to use TLS, specify the TLS port -->	
				<!-- <TLSPort>443</TLSPort> -->	
			</HLS>	
			<DASH>	
				<Port>${env:OME_DASH_STREAM_PORT:8080}</Port>	
				<WorkerCount>1</WorkerCount>	
				<!-- If you want to use TLS, specify the TLS port -->	
				<!-- <TLSPort>443</TLSPort> -->	
			</DASH>	
			<WebRTC>	
				<Signalling>	
					<Port>${env:OME_SIGNALLING_PORT:3333}</Port>	
					<WorkerCount>4</WorkerCount>	
					<!-- If you want to use TLS, specify the TLS port -->	
					<TLSPort>3334</TLSPort>	
				</Signalling>	
				<IceCandidates>	
					<TcpRelay>${env:OME_TCP_RELAY_ADDRESS:*:3478}</TcpRelay>	
					<TcpForce>false</TcpForce>	
					<TcpRelayWorkerCount>4</TcpRelayWorkerCount>	
					<IceCandidate>${env:OME_ICE_CANDIDATES:*:10006/udp}</IceCandidate>	
				</IceCandidates>	
			</WebRTC>	
		</Publishers>

Configuring the Edge

For the edge, basically repeat the step for the origin server; the only difference is the configuration file.

You can basically reuse your origin’s configuration file as it is mostly the same, just modify it as needed. But most importantly, you need to add an origin in the virtual host section and add the edge’s hostname/IP.

Start by adding your Origin in the VirtualHost section of the configuration.

<VirtualHosts>
		<!--
			You can include multiple XML files by doing the following:
			<VirtualHost include="sites-enabled/*.xml" />
		-->
		<VirtualHost include="VHost*.xml" />
		<VirtualHost>
			<Origins>
				<Properties>
					<NoInputFailoverTimeout>3000</NoInputFailoverTimeout>
					<UnusedStreamDeletionTimeout>60000</UnusedStreamDeletionTimeout>
				</Properties>
				<Origin>
					<Location>/app/</Location>
					<Pass>
						<Scheme>OVT</Scheme>
						<Urls><Url>your.origin.ip:9000/app/</Url></Urls>
					</Pass>
				</Origin>
			</Origins>

Following that, add your edge’s IP in the hostname.

<Host>
				<Names>
					<!-- Host names
						<Name>stream1.airensoft.com</Name>
						<Name>stream2.airensoft.com</Name>
						<Name>*.sub.airensoft.com</Name>
						<Name>192.168.0.1</Name>
					-->
					<Name>192.168.2.69</Name>
					<Name>192.168.1.69</Name>
					<Name>*.domain.com</Name>
				</Names>
				
				<TLS>
					<CertPath>/letsencrypt/live/leejacksonz.com/cert.pem</CertPath>
					<KeyPath>/letsencrypt/live/leejacksonz.com/privkey.pem</KeyPath>
					<ChainCertPath>/letsencrypt/live/leejacksonz.com/chain.pem</ChainCertPath>
				</TLS>
				
			</Host>

And well, that is all for the configuration side of things.

Using the Edge Server

Using the edge server is quite simple and elegant. All you do is to just replace your origin server’s address with the edge server’s address. In other words, “your.address” points to the address of your edge server. The edge server will automatically request for the same applications from the origin server, so all the configuration stuff from your origin server still applies.

WebRTC : ws(s)://your.address:port/app/stream
HLS  : http(s)://your.address:port/app/stream/playlist.m3u8
DASH : http(s)://your.address:port/app/stream/manifest.mpd
LLDASH : http(s)://your.address:port/app/stream/manifest_ll.mpd

Some Advice/Tips

For my configuration, I’m using Wireguard VPN for my point-to-point traffic, but it is totally up to you if you wanna do something else. I won’t go into detail on how to do that, but I’d highly recommend you use VPN to secure your traffic.

For my configuration, there are a few problems. One, my home server is running dynamic IP, so whenever there is a change in my IP, the Wireguard connection will stop working. To overcome that, I have this script that I modified that checks for connection from my edge to my server.

while [[ $tries -lt 3 ]]
do
    if /bin/ping -c 1 ip.of.your.origin
    then
        logger -t "wg-watchdog" "wireguard working"
        exit 0
    fi
    tries=$((tries+1))
done
sudo wg-quick down wg0
sleep 5
sudo wg-quick up wg0
logger -t "wg-watchdog" "wireguard restarted"

Save this script, make it executable(see chmod +x) and create a crontab entry for it. In my case, I make it check every minute but feel free to modify it.

crontab -e
* * * * * /bin/bash /path/to/wgWatchdog.sh >/dev/null 2>&1 | logger -t wg-watchdog-cron

Another challenge you will face is syncing your certificate between your servers. Let’s Encrypt certs have expiry and certbot will automatically renew it for you, but when it does that it obviously the certificate file will change. For this, I used rsync to sync the certbot folder between my machines.

I won’t go into detail on how to configure this as it has been a while since I last configured it.

0 0 * * * rsync -a [email protected]:/etc/letsencrypt/ /etc/letsencrypt/

Some Closing Words…

Well, that is all for now. I’m still constantly tweaking my setup and will update this post accordingly. I’ve done some testing and tuning of my own and I’ll be adding that next. Stay tuned!

One thought on “ Getting OvenMediaEngine To Work ”

Leave a Reply